"""IPAM API路由."""

from typing import List, Optional

from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.ext.asyncio import AsyncSession

from netsphere.core.database import get_db
from netsphere.models.ipam import IPAddress, IPNetwork, VLAN, VRF
from netsphere.schemas.ipam import (
    IPAddressCreate,
    IPAddressResponse,
    IPNetworkCreate,
    IPNetworkResponse,
    VLANCreate,
    VLANResponse,
    VRFCreate,
    VRFResponse,
)
from netsphere.services.ipam import IPAMManager, IPAllocator

router = APIRouter()


@router.post("/vrf", response_model=VRFResponse)
async def create_vrf(
    vrf: VRFCreate,
    db: AsyncSession = Depends(get_db),
):
    """创建VRF."""
    manager = IPAMManager(db)
    try:
        return await manager.create_vrf(
            name=vrf.name,
            rd=vrf.rd,
            description=vrf.description,
        )
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.get("/vrf", response_model=List[VRFResponse])
async def list_vrfs(
    db: AsyncSession = Depends(get_db),
):
    """列出所有VRF."""
    # 实现查询逻辑
    pass


@router.post("/vlan", response_model=VLANResponse)
async def create_vlan(
    vlan: VLANCreate,
    db: AsyncSession = Depends(get_db),
):
    """创建VLAN."""
    manager = IPAMManager(db)
    try:
        return await manager.create_vlan(
            vid=vlan.vid,
            name=vlan.name,
            description=vlan.description,
        )
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.get("/vlan", response_model=List[VLANResponse])
async def list_vlans(
    db: AsyncSession = Depends(get_db),
):
    """列出所有VLAN."""
    # 实现查询逻辑
    pass


@router.post("/network", response_model=IPNetworkResponse)
async def create_network(
    network: IPNetworkCreate,
    db: AsyncSession = Depends(get_db),
):
    """创建网络."""
    manager = IPAMManager(db)
    try:
        return await manager.create_network(
            network=network.network,
            prefix_length=network.prefix_length,
            description=network.description,
            vrf_id=network.vrf_id,
            vlan_id=network.vlan_id,
        )
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.get("/network", response_model=List[IPNetworkResponse])
async def list_networks(
    vrf_id: Optional[int] = Query(None, description="VRF ID"),
    vlan_id: Optional[int] = Query(None, description="VLAN ID"),
    is_active: Optional[bool] = Query(None, description="是否活跃"),
    db: AsyncSession = Depends(get_db),
):
    """列出网络."""
    manager = IPAMManager(db)
    return await manager.list_networks(
        vrf_id=vrf_id,
        vlan_id=vlan_id,
        is_active=is_active,
    )


@router.get("/network/{network_id}/utilization")
async def get_network_utilization(
    network_id: int,
    db: AsyncSession = Depends(get_db),
):
    """获取网络使用率."""
    manager = IPAMManager(db)
    try:
        total, used, utilization = await manager.get_network_utilization(network_id)
        return {
            "network_id": network_id,
            "total_addresses": total,
            "used_addresses": used,
            "utilization_percent": utilization,
        }
    except ValueError as e:
        raise HTTPException(status_code=404, detail=str(e))


@router.post("/address/allocate", response_model=IPAddressResponse)
async def allocate_ip(
    allocation: IPAddressCreate,
    db: AsyncSession = Depends(get_db),
):
    """分配IP地址."""
    allocator = IPAllocator(db)
    try:
        ip = await allocator.allocate_ip(
            network_id=allocation.network_id,
            hostname=allocation.hostname,
            description=allocation.description,
            mac_address=allocation.mac_address,
            specific_ip=allocation.address,
        )
        if not ip:
            raise HTTPException(status_code=400, detail="No available IP addresses")
        return ip
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.post("/address/{ip_id}/release")
async def release_ip(
    ip_id: int,
    db: AsyncSession = Depends(get_db),
):
    """释放IP地址."""
    allocator = IPAllocator(db)
    if not await allocator.release_ip(ip_id):
        raise HTTPException(status_code=404, detail="IP address not found or not assigned")
    return {"message": "IP address released successfully"}


@router.get("/address/search")
async def search_ip(
    ip_address: str = Query(..., description="IP地址"),
    db: AsyncSession = Depends(get_db),
):
    """搜索IP地址."""
    manager = IPAMManager(db)
    ip = await manager.search_ip(ip_address)
    if not ip:
        raise HTTPException(status_code=404, detail="IP address not found")
    return ip